﻿// Decompiled with JetBrains decompiler
// Type: Netick.NetworkUnorderedList`1
// Assembly: Netick, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: 6726ECA1-C773-4CF7-8952-E81B30D93B52
// Assembly location: D:\WorkSpaceDemo\UPM\NetickForUnity\Netick\Runtime\Netick.dll
// XML documentation location: D:\WorkSpaceDemo\UPM\NetickForUnity\Netick\Runtime\Netick.xml

using System;
using System.Collections;
using System.Collections.Generic;

#nullable disable
namespace Netick;

/// <summary>
/// A networked list collection. This is an unordered list meaning that the order of the elements during iteration is undefined.
/// </summary>
public sealed class NetworkUnorderedList<T> : 
  NetworkUnorderedList,
  INetworkCollection,
  IEnumerable<T>,
  IEnumerable
  where T : unmanaged
{
  private List<T> _original;

  public NetworkUnorderedList(int capacity)
  {
    this._length = capacity;
    this._original = new List<T>(capacity);
  }

  public override unsafe void InternalInit(
    INetickNetworkScript beh,
    int* state,
    int elementSizeWords,
    int flags)
  {
    base.InternalInit(beh, state, elementSizeWords, flags);
    this._elementSizeWords = NetickUtils.GetWordSize(sizeof (T));
  }

  public IEnumerator<T> GetEnumerator()
  {
    int count = this.Count;
    for (int i = 0; i < count; ++i)
      yield return this.GetElementData(i);
  }

  IEnumerator IEnumerable.GetEnumerator() => (IEnumerator) this.GetEnumerator();

  internal unsafe void SetElementData(int index, T value)
  {
    this._entity.SetState_Collection((int*) &value, this._intS + 1 + index * this._elementSizeWords, this._elementSizeWords, 0, (this._flags & NetworkCollectionMeta.IsInputSourceOnly) == NetworkCollectionMeta.IsInputSourceOnly ? 1 : 0, (this._flags & NetworkCollectionMeta.IsInputSourceOnly) == NetworkCollectionMeta.IsInputSourceOnly ? 1 : 0);
  }

  internal unsafe T GetElementData(int index)
  {
    return *(T*) (this._intS + 1 + index * this._elementSizeWords);
  }

  /// <summary>Gets the number of items contained in the list.</summary>
  public unsafe int Count
  {
    get => (IntPtr) this._intS == IntPtr.Zero ? this._original.Count : *this._intS;
    internal set
    {
      this._entity.SetState_Collection(&value, this._intS, 1, (this._flags & NetworkCollectionMeta.HasOnChanged) == NetworkCollectionMeta.HasOnChanged ? 1 : 0, (this._flags & NetworkCollectionMeta.IsInputSourceOnly) == NetworkCollectionMeta.IsInputSourceOnly ? 1 : 0, (this._flags & NetworkCollectionMeta.IsInputSourceOnly) == NetworkCollectionMeta.IsInputSourceOnly ? 1 : 0);
    }
  }

  /// <summary>Removes all elements from the list.</summary>
  public void Clear() => this.Count = 0;

  /// <summary>Adds an item to the list.</summary>
  /// <param name="item">The item to add.</param>
  /// <returns>True if the item was added; otherwise, false.</returns>
  public unsafe bool Add(T item)
  {
    if ((IntPtr) this._intS == IntPtr.Zero)
    {
      this._original.Add(item);
      return true;
    }
    if (this.Count >= this._length)
      return false;
    this.SetElementData(this.Count, item);
    ++this.Count;
    return true;
  }

  /// <summary>Removes an item from the list.</summary>
  /// <param name="item">The item to add.</param>
  /// <returns>True if the item was removed; otherwise, false.</returns>
  public bool Remove(T item)
  {
    for (int index = 0; index < this.Count; ++index)
    {
      if (EqualityComparer<T>.Default.Equals(this.GetElementData(index), item))
      {
        this.SetElementData(index, this.GetElementData(this.Count - 1));
        --this.Count;
        return true;
      }
    }
    return false;
  }

  public override void InternalReset()
  {
    for (int index = 0; index < this._length; ++index)
      this.SetElementData(index, default (T));
    int index1 = 0;
    foreach (T obj in this._original)
    {
      this.SetElementData(index1, obj);
      ++index1;
    }
    this.Count = this._original.Count;
  }
}
